package lava.rt.persistence;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;

import java.util.ArrayList;

import java.util.List;

import lava.rt.expcption.PersistenceExecption;





public abstract class Entity   {

	

	public abstract Object thisPk();
	
        
	     
	public abstract Class<? extends Entity> thisClass();
	
	
	public abstract void clear();
	
	
	     
	
	



	public final void verify() throws PersistenceExecption {
		Field[] fields = this.thisClass().getDeclaredFields();
		List<String> ret = new ArrayList<>();
		try {
			for (Field field : fields) {
				String key=field.getName();
				field.setAccessible(true);
				ColumnMeta columnMeta = field.getAnnotation(ColumnMeta.class);
				if (columnMeta == null)
					continue;
				Object value = field.get(this);
				if (value == null) {
					if (columnMeta.nullable()) {
						continue;
					} else {
						ret.add(key+ columnMeta.comments() + " is required" );
					}
				} else if (value instanceof String) {

					if (value.toString().length() > columnMeta.dataLength()) {
						ret.add(key+":"+value.toString()+
								" overlay for " + columnMeta.dataLength() );
					}
				}
			}
		} catch (IllegalArgumentException | IllegalAccessException e) {}
		if(ret.size()>0) {
			PersistenceExecption lex= new PersistenceExecption("verify","verify"); 
			lex.issueStackTrace.addAll(ret);
			throw lex;
		}
	}
	
	
	
	
	
	


	@Documented
	@Target(ElementType.FIELD)
	@Retention(RetentionPolicy.RUNTIME)
	public @interface ColumnMeta {

		int dataLength();

		String comments();

		boolean nullable();

	}

	@Documented
	@Target(ElementType.TYPE)
	@Retention(RetentionPolicy.RUNTIME)
	public @interface ObjectMeta {

		String comments();

	}
	
	
	
	
}
